#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@File   : test07_network_management.py
@Time : 2025/2/7 17:04
@Author: Wangwc
@Describe:  网络&安全相关测试用例
"""
import time
import os
import allure
import pytest
import random
import warnings

warnings.filterwarnings("ignore", category=DeprecationWarning)
from urllib3.exceptions import InsecureRequestWarning

warnings.simplefilter('ignore', category=InsecureRequestWarning)

from utils.network_tools import Network
from business.NetworkApi import NetworkApi
from utils.login import Login
from commons.logger import log
from utils.config_tools import Config
from commons.fake_data import Fake
from config.path import CERTS_DIR


# TODO 当前模块的配置文件名称，配置在config目录下
config_name = "user.ini"
login = Login(config_name=config_name)
config = Config(config_name=config_name)

# @pytest.fixture(scope="function")
# def network_api():
#     """
#     用于初始化NetworkApi客户端的夹具
#     """
#     login.http_request.update_base_url()
#     token = login.login()
#     api = NetworkApi(token,configname=config_name)
#     # 动态更新 base_url
#     api.http.update_base_url()
#     return api

global_token = None

@pytest.fixture(scope="function")
def network_api():
    global global_token
    if global_token is None:
        login.http_request.update_base_url()
        global_token = login.login()
    api = NetworkApi(global_token, configname=config_name)
    # 动态更新 base_url
    api.http.update_base_url()
    return api


def handle_api_call(api_method, *args, attach_to_allure=True, format_result=None, **kwargs):
    if not callable(api_method):
        raise TypeError("api_method 参数必须是可调用对象（如函数或方法）")
    if attach_to_allure is not None and not isinstance(attach_to_allure, bool):
        raise TypeError("attach_to_allure 参数必须是布尔类型或者为 None")
    if format_result is not None and not callable(format_result):
        raise TypeError("format_result 参数必须是可调用对象（如函数）或者为 None")

    max_retries = 3
    for retry in range(max_retries):
        try:
            result = api_method(*args, **kwargs)
            if attach_to_allure:
                if format_result:
                    formatted_result = format_result(result)
                else:
                    formatted_result = str(result)
                allure.attach(formatted_result, f"{api_method.__name__} 调用结果", allure.attachment_type.TEXT)
            log.info(f"{api_method.__name__} 调用成功")
            return result
        except Exception as e:
            allure.attach(str(e), f"{api_method.__name__} 调用错误信息", allure.attachment_type.TEXT)
            log.error(f"{api_method.__name__} 调用出现错误: {e}", exc_info=True)
            # 假设根据错误信息判断 token 过期
            if "token 过期" in str(e) and retry < max_retries - 1:
                global global_token
                global_token = login.login()
                api_method.__self__.token = global_token
                continue
            elif isinstance(e, ConnectionError):
                log.error("连接错误，可能是网络问题，请检查网络连接。")
            elif isinstance(e, ValueError):
                log.error("值错误，可能是传入的参数有误，请检查参数。")
            raise


@allure.feature("控制面板-网络&安全")
class TestSystemManagement():
    @allure.title("默认DNS服务器信息")
    def test_start_ftp(self, network_api):
        with allure.step("获取网络通用设置信息"):
            results = handle_api_call(network_api.get_network_general)

        with allure.step("确认使用默认DNS服务器信息"):
            dns = results.get('general').get('dns_mode')
            dns_list = results.get('general').get('dns')
            assert dns == 0
            assert dns_list == ['202.96.134.133', '202.96.128.86']

    @allure.title("IPV4默认网关")
    def test_ipv4_gateway(self, network_api):
        with allure.step("获取网关信息"):
            results = handle_api_call(network_api.get_gateway)

        with allure.step("确认使用默认DNS服务器信息"):
            ipv4_gateway = config.read_config_ini('gateway', 'ipv4')
            acturl_gateway = results.get('ipv4')[0].get('gateway')
            assert acturl_gateway == ipv4_gateway, f"网关信息不正确，期望值：{ipv4_gateway}，实际值：{acturl_gateway}"

    @allure.title("开启优先使用IPV4地址解析域名")
    def test_start_ipv4_prior(self, network_api):
        with allure.step("获取网络基本配置信息"):
            results = handle_api_call(network_api.get_network_general)
            general = results.get('general')
            proxy = results.get('proxy')

        with allure.step("开启优先使用IPV4地址解析域名"):
            general['prior_ipv4'] = 1
            handle_api_call(network_api.set_network_general,general,proxy)

        with allure.step("再次获取网络基本配置信息"):
            new_results = handle_api_call(network_api.get_network_general)
            new_general = new_results.get('general')
            assert new_general == general,f"优先使用IPV4地址解析域名未开启，期望值：{general}，实际值：{new_general}"

        with allure.step("SSH登录终端确认"):
            command = 'cat /etc/gai.conf'
            hostname = config.read_config_ini('envHost', 'hostname')
            username = config.read_config_ini('user', 'user_name')
            password = config.read_config_ini('user', 'user_pwd')
            result = handle_api_call(network_api.check_ipv4_prior,hostname,username,password,command)
            assert 'precedence ::ffff:0:0/96  100' in result

    @allure.title("关闭优先使用IPV4地址解析域名")
    def test_stop_ipv4_prior(self, network_api):
        with allure.step("获取网络基本配置信息"):
            results = handle_api_call(network_api.get_network_general)
            general = results.get('general')
            proxy = results.get('proxy')

        with allure.step("关闭优先使用IPV4地址解析域名"):
            general['prior_ipv4'] = 0
            handle_api_call(network_api.set_network_general, general, proxy)

        with allure.step("再次获取网络基本配置信息"):
            new_results = handle_api_call(network_api.get_network_general)
            new_general = new_results.get('general')
            assert new_general == general, f"优先使用IPV4地址解析域名未开启，期望值：{general}，实际值：{new_general}"

        with allure.step("SSH登录终端确认"):
            command = 'cat /etc/gai.conf'
            hostname = config.read_config_ini('envHost', 'hostname')
            username = config.read_config_ini('user', 'user_name')
            password = config.read_config_ini('user', 'user_pwd')
            result = handle_api_call(network_api.check_ipv4_prior, hostname, username, password, command)
            assert '# precedence ::ffff:0:0/96  100' in result

    @allure.title("开启与关闭多网关")
    def test_multiple_gateways(self, network_api):
        with allure.step("获取网络基本配置信息"):
            results = handle_api_call(network_api.get_network_general)
            general = results.get('general')
            proxy = results.get('proxy')

        with allure.step("开启多网关"):
            general['multiple_gateways'] = 1
            handle_api_call(network_api.set_network_general, general, proxy)

        with allure.step("再次获取网络基本配置信息"):
            new_results = handle_api_call(network_api.get_network_general)
            assert new_results.get('general').get('multiple_gateways') == 1

        with allure.step("关闭多网关"):
            general['multiple_gateways'] = 0
            handle_api_call(network_api.set_network_general, general, proxy)

        with allure.step("再次获取网络基本配置信息"):
            new_results = handle_api_call(network_api.get_network_general)
            assert new_results.get('general').get('multiple_gateways') == 0

    @allure.title("开启与关闭IP冲突检测")
    def test_clash_check(self, network_api):
        with allure.step("获取网络基本配置信息"):
            results = handle_api_call(network_api.get_network_general)
            general = results.get('general')
            proxy = results.get('proxy')

        with allure.step("开启IP冲突检测"):
            general['clash_check'] = 1
            handle_api_call(network_api.set_network_general, general, proxy)

        with allure.step("再次获取网络基本配置信息"):
            new_results = handle_api_call(network_api.get_network_general)
            assert new_results.get('general').get('clash_check') == 1

        with allure.step("关闭IP冲突检测"):
            general['clash_check'] = 0
            handle_api_call(network_api.set_network_general, general, proxy)

        with allure.step("再次获取网络基本配置信息"):
            new_results = handle_api_call(network_api.get_network_general)
            assert new_results.get('general').get('clash_check') == 0

    @allure.title("创建bond")
    def test_create_bond(self, network_api):
        with allure.step("获取可选用的网卡"):
            interfaces = handle_api_call(network_api.get_network_iface_list, interface='valid_eth')
            slaves = [iface.get('interface') for iface in interfaces]

        with allure.step("创建bond"):
            handle_api_call(network_api.create_bond, slaves)
            time.sleep(25)

        with allure.step("重新获取设备IP"):
            api = Network()
            try:
                network_prefix = config.read_config_ini('device', 'network_prefix').split(',')
                nasname = config.read_config_ini('device', 'device_name')
                ip = api.get_ip_by_prefix(network_prefix, nasname)
                print(f"获取到的设备 IP 地址是: {ip}")
            except Exception as e:
                print(f"获取 IP 地址时出现异常: {e}")

        with allure.step("确认并更新设备IP"):
            host = config.read_config_ini('envHost','hostname')
            if host != ip and ip is not None:
                config.set_config_ini('envHost','hostname',ip)
                config.set_config_ini('envHost','host',f"http://{ip}:9999")
                handle_api_call(network_api.http.update_base_url)
                time.sleep(1)
                log.info(f"成功更新设备IP为: {ip}")
            else:
                log.info(f"IP地址没有变更，无需更改")

        with allure.step("等待bond创建完成并验证"):
            if handle_api_call(network_api.check_bond_status,2):
                ifaces = handle_api_call(network_api.get_network_iface_list)
                bond_mode = ifaces[0].get('bond_mode')
                assert bond_mode == "balance-alb",f"创建bond失败，预计bond：balance-alb，实际bond：{bond_mode}"

    @allure.title("删除bond")
    def test_delete_bond(self, network_api):
        log.info(f"开始执行删除BOND测试用例")
        with allure.step("获取网卡信息"):
            ifaces = handle_api_call(network_api.get_network_iface_list)

        with allure.step("删除bond"):
            handle_api_call(network_api.delete_bond)

        with allure.step("等待bond删除完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                new_ifaces = handle_api_call(network_api.get_network_iface_list)
                assert new_ifaces != ifaces, f"删除bond失败，删除bond前后网卡信息一致"

    @allure.title("创建bond0")
    def test_create_bond0(self, network_api):
        with allure.step("获取可选用的网卡"):
            interfaces = handle_api_call(network_api.get_network_iface_list, interface='valid_eth')
            slaves = [iface.get('interface') for iface in interfaces]

        with allure.step("创建bond0"):
            handle_api_call(network_api.create_bond, slaves,bond_mode='balance-rr')
            time.sleep(25)

        with allure.step("重新获取设备IP"):
            api = Network()

            try:
                network_prefix = config.read_config_ini('device', 'network_prefix').split(',')
                nasname = config.read_config_ini('device', 'device_name')
                ip = api.get_ip_by_prefix(network_prefix, nasname)
                print(f"获取到的设备 IP 地址是: {ip}")
            except Exception as e:
                print(f"获取 IP 地址时出现异常: {e}")

        with allure.step("确认并更新设备IP"):
            host = config.read_config_ini('envHost', 'hostname')
            if host != ip and ip is not None:
                config.set_config_ini('envHost', 'hostname', ip)
                config.set_config_ini('envHost', 'host', f"http://{ip}:9999")
                handle_api_call(network_api.http.update_base_url)
                time.sleep(1)
                log.info(f"成功更新设备IP为: {ip}")
            else:
                log.info(f"IP地址没有变更，无需更改")

        with allure.step("等待bond创建完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                ifaces = handle_api_call(network_api.get_network_iface_list)
                bond_mode = ifaces[0].get('bond_mode')
                assert bond_mode == "balance-rr", f"创建bond0失败，预计bond：balance-rr，实际bond：{bond_mode}"

        with allure.step("删除bond0"):
            handle_api_call(network_api.delete_bond)

        with allure.step("等待bond0删除完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                new_ifaces = handle_api_call(network_api.get_network_iface_list)
                assert new_ifaces != ifaces, f"删除bond失败，删除bond前后网卡信息一致"

    @allure.title("创建bond1")
    def test_create_bond1(self, network_api):
        with allure.step("获取可选用的网卡"):
            interfaces = handle_api_call(network_api.get_network_iface_list, interface='valid_eth')
            slaves = [iface.get('interface') for iface in interfaces]

        with allure.step("创建bond1"):
            handle_api_call(network_api.create_bond, slaves, bond_mode='active-backup')
            time.sleep(25)

        with allure.step("重新获取设备IP"):
            api = Network()

            try:
                network_prefix = config.read_config_ini('device', 'network_prefix').split(',')
                nasname = config.read_config_ini('device', 'device_name')
                ip = api.get_ip_by_prefix(network_prefix, nasname)
                print(f"获取到的设备 IP 地址是: {ip}")
            except Exception as e:
                print(f"获取 IP 地址时出现异常: {e}")

        with allure.step("确认并更新设备IP"):
            host = config.read_config_ini('envHost', 'hostname')
            if host != ip and ip is not None:
                config.set_config_ini('envHost', 'hostname', ip)
                config.set_config_ini('envHost', 'host', f"http://{ip}:9999")
                handle_api_call(network_api.http.update_base_url)
                time.sleep(1)
                log.info(f"成功更新设备IP为: {ip}")
            else:
                log.info(f"IP地址没有变更，无需更改")

        with allure.step("等待bond创建完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                ifaces = handle_api_call(network_api.get_network_iface_list)
                bond_mode = ifaces[0].get('bond_mode')
                assert bond_mode == "active-backup", f"创建bond0失败，预计bond：active-backup，实际bond：{bond_mode}"

        with allure.step("删除bond1"):
            handle_api_call(network_api.delete_bond)

        with allure.step("等待bond1删除完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                new_ifaces = handle_api_call(network_api.get_network_iface_list)
                assert new_ifaces != ifaces, f"删除bond1失败，删除bond1前后网卡信息一致"

    @allure.title("创建bond2")
    def test_create_bond2(self, network_api):
        with allure.step("获取可选用的网卡"):
            interfaces = handle_api_call(network_api.get_network_iface_list, interface='valid_eth')
            slaves = [iface.get('interface') for iface in interfaces]

        with allure.step("创建bond2"):
            handle_api_call(network_api.create_bond, slaves, bond_mode='balance-xor')
            time.sleep(25)

        with allure.step("重新获取设备IP"):
            api = Network()
            try:
                network_prefix = config.read_config_ini('device', 'network_prefix').split(',')
                nasname = config.read_config_ini('device', 'device_name')
                ip = api.get_ip_by_prefix(network_prefix, nasname)
                print(f"获取到的设备 IP 地址是: {ip}")
            except Exception as e:
                print(f"获取 IP 地址时出现异常: {e}")
        with allure.step("确认并更新设备IP"):
            host = config.read_config_ini('envHost', 'hostname')
            if host != ip and ip is not None:
                config.set_config_ini('envHost', 'hostname', ip)
                config.set_config_ini('envHost', 'host', f"http://{ip}:9999")
                handle_api_call(network_api.http.update_base_url)
                time.sleep(1)
                log.info(f"成功更新设备IP为: {ip}")
            else:
                log.info(f"IP地址没有变更，无需更改")
        with allure.step("等待bond2创建完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                ifaces = handle_api_call(network_api.get_network_iface_list)
                bond_mode = ifaces[0].get('bond_mode')
                assert bond_mode == "balance-xor", f"创建bond0失败，预计bond：balance-xor，实际bond：{bond_mode}"

        with allure.step("删除bond2"):
            handle_api_call(network_api.delete_bond)

        with allure.step("等待bond2删除完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                new_ifaces = handle_api_call(network_api.get_network_iface_list)
                assert new_ifaces != ifaces, f"删除bond2失败，删除bond2前后网卡信息一致"

    @allure.title("创建bond4")
    def test_create_bond4(self, network_api):
        with allure.step("获取可选用的网卡"):
            interfaces = handle_api_call(network_api.get_network_iface_list, interface='valid_eth')
            slaves = [iface.get('interface') for iface in interfaces]

        with allure.step("创建bond4"):
            handle_api_call(network_api.create_bond, slaves, bond_mode='802.3ad')
            time.sleep(25)

        with allure.step("重新获取设备IP"):
            api = Network()
            try:
                network_prefix = config.read_config_ini('device', 'network_prefix').split(',')
                nasname = config.read_config_ini('device', 'device_name')
                ip = api.get_ip_by_prefix(network_prefix, nasname)
                print(f"获取到的设备 IP 地址是: {ip}")
            except Exception as e:
                print(f"获取 IP 地址时出现异常: {e}")

        with allure.step("确认并更新设备IP"):
            host = config.read_config_ini('envHost', 'hostname')
            if host != ip and ip is not None:
                config.set_config_ini('envHost', 'hostname', ip)
                config.set_config_ini('envHost', 'host', f"http://{ip}:9999")
                handle_api_call(network_api.http.update_base_url)
                time.sleep(1)
                log.info(f"成功更新设备IP为: {ip}")
            else:
                log.info(f"IP地址没有变更，无需更改")

        with allure.step("等待bond4创建完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                ifaces = handle_api_call(network_api.get_network_iface_list)
                bond_mode = ifaces[0].get('bond_mode')
                assert bond_mode == "802.3ad", f"创建bond0失败，预计bond：802.3ad，实际bond：{bond_mode}"

        with allure.step("删除bond4"):
            handle_api_call(network_api.delete_bond)

        with allure.step("等待bond4删除完成并验证"):
            if handle_api_call(network_api.check_bond_status, 2):
                new_ifaces = handle_api_call(network_api.get_network_iface_list)
                assert new_ifaces != ifaces, f"删除bond4失败，删除bond4前后网卡信息一致"

    @allure.title("创建虚拟桥接")
    def test_virtual_brige(self, network_api):
        with allure.step("获取可选用的网卡"):
            interfaces = handle_api_call(network_api.get_network_iface_list,interface='valid_eth')
            slaves = [iface.get('interface') for iface in interfaces]

        with allure.step("创建虚拟桥接"):
            handle_api_call(network_api.create_virtual, slaves)

        with allure.step("等待虚拟桥接创建完成并验证"):
            if handle_api_call(network_api.check_virtual_status, 2):
                time.sleep(1)
                ifaces = handle_api_call(network_api.get_network_iface_list)
                bridge = ifaces[0].get('interface')
                assert "bridge" in bridge, f"创建虚拟桥接失败，预计包含bridge，实际为：{bridge}"

    @allure.title("删除虚拟桥接")
    def test_delete_virtual_brige(self, network_api):
        log.info(f"开始执行删除虚拟桥接测试用例")
        with allure.step("获取网络列表信息"):
            ifaces = handle_api_call(network_api.get_network_iface_list)
            bridge1 = ifaces[0].get('interface')
            bridge2 = ifaces[1].get('interface')

        with allure.step("删除虚拟桥接"):
            handle_api_call(network_api.delete_virtual, bridge1)
            handle_api_call(network_api.delete_virtual, bridge2)
            time.sleep(1)

        with allure.step("等待虚拟桥接删除完成并验证"):
            if handle_api_call(network_api.check_bridge_status, 2):
                time.sleep(1)
                new_ifaces = handle_api_call(network_api.get_network_iface_list)
                new_bridge = new_ifaces[0].get('interface')
                assert new_bridge != bridge1, f"删除虚拟桥接失败，预计没有bridge，实际结果：{new_bridge}"
                assert "bridge" not in new_bridge, f"删除虚拟桥接失败，预计包含不bridge，实际为：{new_bridge}"

    @allure.title("改变网关顺序")
    def test_change_gateway(self, network_api):
        log.info(f"开始执行改变网关顺序测试用例")
        time.sleep(3)
        with allure.step("获取网关信息"):
            gate_way = handle_api_call(network_api.get_gateway)
            ipv4 = gate_way.get('ipv4')
            set_ipv4 = ipv4[::-1]

        with allure.step("更改网关信息"):
            handle_api_call(network_api.set_gateway, set_ipv4)
            time.sleep(10)

        with allure.step("确认网关信息更改"):
            new_gate_way = handle_api_call(network_api.get_gateway)
            new_ipv4 = new_gate_way.get('ipv4')
            assert new_ipv4[0] == set_ipv4[0], f"更改网关信息失败，预计为：{set_ipv4}，实际为：{new_ipv4}"

    @allure.title("设置网络流量控制")
    def test_set_network_flow(self, network_api):
        log.info(f"开始执行设置网络流量控制测试用例")
        with allure.step("获取流量控制列表"):
            result = handle_api_call(network_api.get_network_flow)
            assert result == [] or result is None, f"设置网络流量控制失败，预计为空，实际为：{result}"

        with allure.step("设置网络流量控制"):
            min_rate = random.randint(10, 100)
            max_rate = random.randint(10240, 102400)
            set_list = [{"type": "all", "interface": "all", "min_rate": min_rate, "max_rate": max_rate, "ports": "all",
                         "enable": 1, "target": "src"}]
            handle_api_call(network_api.set_network_flow, set_list)
            time.sleep(1)

        with allure.step("确认流量控制设置成功"):
            new_result = handle_api_call(network_api.get_network_flow)
            new_network_flow_list = new_result[0].get('list')
            assert new_network_flow_list[0].get(
                'min_rate') == min_rate, f"设置网络流量控制失败，预计最小流量为：{min_rate}，实际为：{new_network_flow_list[0].get('min_rate')}"
            assert new_network_flow_list[0].get(
                'max_rate') == max_rate, f"设置网络流量控制失败，预计最大流量为：{max_rate}，实际为：{new_network_flow_list[0].get('max_rate')}"

    @allure.title("删除网络流量控制")
    def test_delete_network_flow(self, network_api):
        log.info(f"开始执行设置网络流量控制测试用例")
        with allure.step("获取流量控制列表"):
            result = handle_api_call(network_api.get_network_flow)
            network_flow_list = result[0].get('list')

        with allure.step("删除网络流量控制"):
            handle_api_call(network_api.clear_network_flow)
            time.sleep(1)

        with allure.step("确认流量控制删除成功"):
            new_result = handle_api_call(network_api.get_network_flow)
            assert new_result == [] or new_result is None, f"删除网络流量控制失败"

    @allure.title("设置静态IPV4")
    def test_set_manual_ipv4(self, network_api):
        log.info(f"获取网口信息")
        with allure.step("获取流量控制列表"):
            interfaces = handle_api_call(network_api.get_bond_selectable)
            interface = interfaces[0]


        with allure.step("获取可用IP、网关、NDS信息"):
            interface_list = handle_api_call(network_api.get_network_iface_list)
            gateway = interface_list[0].get('ipv4').get('gateway')
            netmask = interface_list[0].get('ipv4').get('netmask')
            dns = interface_list[0].get('ipv4').get('dns')
            set_ip = handle_api_call(network_api.find_unused_ip)


        with allure.step("设置静态IP"):
            handle_api_call(network_api.set_network_iface, interface, ipv4_protocol='static', ipv4_ipaddr=set_ip,
                            ipv4_gateway=gateway, ipv4_netmask=netmask, ipv4_dns=dns)
            time.sleep(3)

        with allure.step("重新获取设备IP"):
            api = Network()
            try:
                network_prefix = config.read_config_ini('device', 'network_prefix').split(',')
                nasname = config.read_config_ini('device', 'device_name')
                get_ip = api.get_ip_by_prefix(network_prefix, nasname)
                print(f"获取到的设备 IP 地址是: {get_ip}")
            except Exception as e:
                print(f"获取 IP 地址时出现异常: {e}")

        with allure.step("确认并更新设备IP"):
            host = config.read_config_ini('envHost', 'hostname')
            if host != get_ip and get_ip is not None:
                ip = get_ip
            else:
                ip = set_ip
            config.set_config_ini('envHost', 'hostname', ip)
            config.set_config_ini('envHost', 'host', f"http://{ip}:9999")
            handle_api_call(network_api.http.update_base_url)
            time.sleep(1)
            log.info(f"成功更新设备IP为: {ip}")

        with allure.step("确认静态IP设置成功"):
            new_interface_list = handle_api_call(network_api.get_network_iface_list)
            new_ip = new_interface_list[0].get('ipv4').get('ipaddr')
            protocol = new_interface_list[0].get('ipv4').get('protocol')
            assert new_ip == set_ip, f"设置静态IP失败，预计为：{set_ip}，实际为：{ip}"
            assert protocol == 'static', f"设置静态IP失败，预计为：static，实际为：{protocol}"

    @allure.title("恢复IPV4为DHCP")
    def test_set_dhcp_ipv4(self, network_api):
        log.info(f"获取网口信息")
        with allure.step("获取流量控制列表"):
            interfaces = handle_api_call(network_api.get_bond_selectable)
            interface = interfaces[0]

        with allure.step("设置DHCP"):
            result = handle_api_call(network_api.set_network_iface, interface)
            ip = result[0].get('ipaddr')
            host = config.read_config_ini('envHost', 'hostname')
            if host != ip and ip is not None:
                config.set_config_ini('envHost', 'hostname', ip)
                config.set_config_ini('envHost', 'host', f"http://{ip}:9999")
                handle_api_call(network_api.http.update_base_url)
                time.sleep(1)
                log.info(f"成功更新设备IP为: {ip}")
            else:
                log.info(f"IP地址没有变更，无需更改")

        with allure.step("确认恢复DHCP成功"):
            time.sleep(3)
            new_interface_list = handle_api_call(network_api.get_network_iface_list)
            protocol = new_interface_list[1].get('ipv4').get('protocol')
            assert protocol == 'dhcp', f"恢复dhcp失败，预计为：dhcp，实际为：{protocol}"

    @allure.title("开启dos保护")
    def test_start_dos(self, network_api):
        log.info(f"开始执行开启dos保护测试用例")
        with allure.step("获取安全管理配置"):
            result = handle_api_call(network_api.get_security_common_config)
            dos = result.get('doc_sec_enable')

        with allure.step("开启dos保护"):
            handle_api_call(network_api.set_security_common_config,doc_sec_enable=1)
            time.sleep(1)

        with allure.step("接口确认开启dos保护"):
            new_result = handle_api_call(network_api.get_security_common_config)
            new_dos = new_result.get('doc_sec_enable')
            assert new_dos == 1, f"开启dos保护失败，预计为：1，实际为：{new_dos}"

        with allure.step("SSH登录终端确认开启dos保护"):
            hostname = config.read_config_ini('envHost','hostname')
            username = config.read_config_ini('user','user_name')
            passwd = config.read_config_ini('user','user_pwd')
            is_dos_protection_enabled = handle_api_call(network_api.check_dos_protection,hostname,username,passwd)
            assert is_dos_protection_enabled == True, f"开启dos保护失败，SSH登录终端确认开启dos保护失败，实际为：{is_dos_protection_enabled}"

    @allure.title("关闭dos保护")
    def test_stop_dos(self, network_api):
        log.info(f"开始执行关闭dos保护测试用例")
        with allure.step("获取安全管理配置"):
            result = handle_api_call(network_api.get_security_common_config)
            dos = result.get('doc_sec_enable')

        with allure.step("关闭dos保护"):
            handle_api_call(network_api.set_security_common_config, doc_sec_enable=0)
            time.sleep(1)

        with allure.step("接口确认关闭dos保护"):
            new_result = handle_api_call(network_api.get_security_common_config)
            new_dos = new_result.get('doc_sec_enable')
            assert new_dos == 0, f"关闭dos保护失败，预计为：0，实际为：{new_dos}"

        with allure.step("SSH登录终端确认开启dos保护"):
            hostname = config.read_config_ini('envHost', 'hostname')
            username = config.read_config_ini('user', 'user_name')
            passwd = config.read_config_ini('user', 'user_pwd')
            is_dos_protection_enabled = handle_api_call(network_api.check_dos_protection, hostname, username, passwd)
            assert is_dos_protection_enabled == False, f"开启dos保护失败，SSH登录终端确认开启dos保护失败，实际为：{is_dos_protection_enabled}"

    @allure.title("提高对跨网站请求伪造攻击的保护")
    def test_change_csrf(self, network_api):
        log.info(f"开始执行提高对跨网站请求伪造攻击的保护测试用例")
        with allure.step("获取安全管理配置"):
            result = handle_api_call(network_api.get_security_common_config)
            csrf_enable = result.get('nginx_sec_config').get('csrf_enable')

        with allure.step("更改防伪造攻击保护"):
            set_csrf_enable = 1 if csrf_enable == 0 else 0
            handle_api_call(network_api.set_security_common_config, csrf_enable=set_csrf_enable)
            time.sleep(1)

        with allure.step("接口确认更改防伪造攻击保护"):
            new_result = handle_api_call(network_api.get_security_common_config)
            csrf_enable = new_result.get('nginx_sec_config').get('csrf_enable')
            assert csrf_enable == set_csrf_enable,f"更改防伪造攻击保护失败，预计为：{set_csrf_enable}，实际为：{csrf_enable}"

    @allure.title("黑名单管理")
    def test_blocklist(self, network_api):
        log.info(f"开始执行黑名单管理测试用例")
        with allure.step("添加黑名单"):
            ip1 = f'172.17.21.{random.randint(1, 255)}'
            ip2 = f'172.17.21.{random.randint(1, 255)}'
            addlist = [{"ip":ip1,"days":0},{"ip":ip2,"days":3}]
            handle_api_call(network_api.change_blocklist, addlist=addlist)
            time.sleep(1)

        with allure.step("确认IP成功添加"):
            blocklist = handle_api_call(network_api.get_blocklist)
            assert any(item.get('ip') == ip1 for item in blocklist), f"{ip1} 不在列表中，实际为：{blocklist}"
            assert any(item.get('ip') == ip2 for item in blocklist), f"{ip2} 不在列表中，实际为：{blocklist}"

        with allure.step("删除黑名单"):
            dellist = [item.get('id') for item in blocklist]
            handle_api_call(network_api.change_blocklist, dellist=dellist)
            time.sleep(3)

        with allure.step("确认IP全部删除"):
            new_blocklist = handle_api_call(network_api.get_blocklist)
            assert new_blocklist == None, f"IP删除失败，实际为：{new_blocklist}"

    @allure.title("白名单管理")
    def test_whitelist(self, network_api):
        log.info(f"开始执行白名单管理测试用例")
        with allure.step("添加白名单"):
            ip1 = f'172.17.21.{random.randint(1, 255)}'
            ip2 = f'172.17.21.{random.randint(1, 255)}'
            ip3 = f'172.17.21.{random.randint(1, 255)}'
            addlist = [ip1, ip2,ip3]
            handle_api_call(network_api.change_whitelist, ip_list=addlist)
            time.sleep(1)

        with allure.step("确认IP成功添加"):
            whitelist = handle_api_call(network_api.get_whitelist)
            assert any(item.get('ip_rule') == ip1 for item in whitelist), f"{ip1} 不在列表中，实际为：{whitelist}"
            assert any(item.get('ip_rule') == ip2 for item in whitelist), f"{ip2} 不在列表中，实际为：{whitelist}"
            assert any(item.get('ip_rule') == ip3 for item in whitelist), f"{ip3} 不在列表中，实际为：{whitelist}"

        with allure.step("删除白名单"):
            dellist = [item.get('id') for item in whitelist]
            handle_api_call(network_api.change_whitelist, dellist=dellist)
            time.sleep(3)

        with allure.step("确认IP全部删除"):
            new_whitelist = handle_api_call(network_api.get_whitelist)
            assert new_whitelist == None, f"IP删除失败，实际为：{new_whitelist}"

    @allure.title("新增防火墙规则")
    def test_add_firewall(self, network_api):
        log.info(f"开始执行新增防火墙规则测试用例")
        with allure.step("获取防火墙规则列表"):
            results = handle_api_call(network_api.get_firewall_info)
            firewall_list = results.get('nameList')

        with allure.step("新增防火墙规则"):
            ename = Fake.generate_english_username()
            firewall_name = f"防火墙规则{ename}"
            port = random.randint(2000,3000)
            port_info = {'ports': str(port)}
            handle_api_call(network_api.add_firewall_rule, name=firewall_name,port_info=port_info)

        with allure.step("确认新增防火墙规则"):
            new_results = handle_api_call(network_api.get_firewall_info)
            new_firewall_list = new_results.get('nameList')
            assert len(new_firewall_list) == len(firewall_list) + 1, f"新增防火墙规则失败，实际为：{new_firewall_list}"

    @allure.title("删除防火墙规则")
    def test_del_firewall(self, network_api):
        log.info(f"开始执行删除防火墙规则测试用例")
        with allure.step("获取防火墙规则列表"):
            results = handle_api_call(network_api.get_firewall_info)
            firewall_list = results.get('nameList')

        with allure.step("删除防火墙规则"):
            nameList1 = firewall_list[0]
            handle_api_call(network_api.del_firewall_rule, [nameList1])

        with allure.step("确认删除防火墙规则"):
            new_results = handle_api_call(network_api.get_firewall_info)
            new_firewall_list = new_results.get('nameList')
            assert len(new_firewall_list) == len(firewall_list) - 1, f"删除防火墙规则失败，实际为：{new_firewall_list}"

    @allure.title("关闭防火墙")
    def test_stop_firewall(self, network_api):
        log.info(f"开始执行关闭防火墙测试用例")
        with allure.step("获取防火墙信息"):
            results = handle_api_call(network_api.get_firewall_info)
            firewall_list = results.get('nameList')

        with allure.step("关闭防火墙"):
            set_enable = 0
            handle_api_call(network_api.set_firewall, set_enable,firewall_list)

        with allure.step("确认关闭防火墙"):
            new_results = handle_api_call(network_api.get_firewall_info)
            new_enable = new_results.get('enable')
            assert new_enable == set_enable, f"关闭防火墙失败，预期状态为：{set_enable}，实际状态为：{new_enable}"

    @allure.title("证书延期")
    def test_extend_ssl_security(self, network_api):
        log.info(f"开始执行证书延期测试用例")
        with allure.step("获取当前证书信息"):
            results = handle_api_call(network_api.get_ssl_list)
            expired = results[0].get('expired')
            issuer = results[0].get('issuer')

        with allure.step("证书延期"):
            handle_api_call(network_api.extend_ssl_security, issuer)
            time.sleep(3)

        with allure.step("确认证书延期"):
            new_results = handle_api_call(network_api.get_ssl_list)
            new_expired = new_results[0].get('expired')
            assert new_expired > expired, f"证书延期失败，预期时间戳大于{expired}，实际为：{new_expired}"

    @allure.title("导入证书")
    def test_import_ssl_security(self, network_api):
        log.info(f"开始执行导入证书测试用例")
        with allure.step("获取当前证书信息"):
            results = handle_api_call(network_api.get_ssl_list)

        with allure.step("获取待导入证书信息"):
            perm_name = config.read_config_ini('certs','perm_name')
            cert_name = config.read_config_ini('certs','cert_name')
            perm_path = os.path.join(CERTS_DIR,perm_name)
            cert_path = os.path.join(CERTS_DIR,cert_name)
            perm_content = handle_api_call(network_api.read_files, perm_path)
            log.info(f"获取到的密钥文件内容为：{perm_content}")
            cert_content = handle_api_call(network_api.read_files, cert_path)
            log.info(f"获取到的证书文件内容为：{cert_content}")


        with allure.step("导入证书"):
            handle_api_call(network_api.import_ssl_security, perm_content, cert_content)
            time.sleep(3)

        with allure.step("确认导入证书"):
            new_results = handle_api_call(network_api.get_ssl_list)
            assert len(new_results) == len(results)+1, f"导入证书失败，预期证书数量：{len(results)+1}，实际为：{len(new_results)}"

    @allure.title("删除证书")
    def test_del_ssl_security(self, network_api):
        log.info(f"开始执行删除证书测试用例")
        with allure.step("获取当前证书信息"):
            results = handle_api_call(network_api.get_ssl_list)
            cert_name = results[-1].get('subject')

        with allure.step("删除证书"):
            handle_api_call(network_api.del_ssl_security, cert_name)
            time.sleep(3)

        with allure.step("确认导入证书"):
            new_results = handle_api_call(network_api.get_ssl_list)
            assert len(new_results) == len(results)-1, f"删除证书失败，预期证书数量：{len(results)-1}，实际为：{len(new_results)}"






